package com.hjc.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateRange;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.hjc.db.dao.*;
import com.hjc.db.pojo.TbCheckin;
import com.hjc.domain.vo.CheckinVo;
import com.hjc.dto.CheckDateDto;
import com.hjc.dto.UserIdDto;
import com.hjc.dto.SystemConstants;
import com.hjc.dto.TimeRangeBaseDto;
import com.hjc.exception.EmosException;
import com.hjc.service.CheckinService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.*;

@Service
@Scope("prototype")
@Slf4j
public class CheckinServiceImpl implements CheckinService {
    @Autowired
    private SystemConstants constants;
    @Autowired
    private TbHolidaysDao holidaysDao;
    @Autowired
    private TbWorkdayDao workdayDao;
    @Autowired
    private TbCheckinDao checkinDao;
    @Autowired
    private TbCityDao tbCityDao;
    @Autowired
    private TbImagePathDao tbImagePathDao;

    @Override
    public String validCanCheckIn(int userId, String date) {
        boolean b1 = holidaysDao.searchTodayIsHolidays() != null;
        boolean b2 = workdayDao.searchTodayIsWorkday() != null;
        String type = "工作日";
        if (DateUtil.date().isWeekend()) {
            type = "节假日";
        }
        if (b1) {
            type = "节假日";
        } else if (b2) {
            type = "工作日";
        }

        if (type.equals("节假日")) {
            return "节假日不需要考勤";
        } else {
            DateTime now = DateUtil.date();
            String start = DateUtil.today() + " " + constants.getAttendanceStartTime();
            String end = DateUtil.today() + " " + constants.getAttendanceEndTime();
            DateTime attendanceStart = DateUtil.parse(start);
            DateTime attendanceEnd = DateUtil.parse(end);
            if (now.isBefore(attendanceStart)) {
                return "未到上班考勤开始时间";
            } else if (now.isAfter(attendanceEnd)) {
                return "超出上班考勤结束时间";
            } else {
                HashMap map = new HashMap();
                map.put("userId", userId);
                map.put("date", date);
                map.put("start", start);
                map.put("end", end);
                boolean bool = checkinDao.haveCheckin(map) != null;
                return bool ? "今日已考勤" : "可以考勤";
            }
        }
    }

    @Override
    public void checkin(HashMap param) {
        Date d1 = DateUtil.date();
        Date d2 = DateUtil.parse(DateUtil.today() + " " + constants.getAttendanceTime());
        Date d3 = DateUtil.parse(DateUtil.today() + " " + constants.getAttendanceEndTime());
        int status = 1;
        if (d1.compareTo(d2) <= 0) {
            status = 1;
        } else if (d1.compareTo(d2) > 0 && d1.compareTo(d3) < 0) {
            status = 2;
        } else {
            throw new EmosException("超出考勤时间段，无法考勤");
        }
        int userId = (Integer) param.get("userId");

        //查询疫情风险等级
        int risk = 1;
        String city = (String) param.get("city");
        String district = (String) param.get("district");
        String address = (String) param.get("address");
        String country = (String) param.get("country");
        String province = (String) param.get("province");
        log.error(address);
        TbCheckin entity = new TbCheckin();
        entity.setUserId(userId);
        entity.setAddress(address);
        entity.setCountry(country);
        entity.setProvince(province);
        entity.setCity(city);
        entity.setDistrict(district);
        entity.setStatus((byte) status);
        entity.setRisk(risk);
        entity.setDate(DateUtil.today());
        entity.setCreateTime(d1);
        checkinDao.insert(entity);
    }

    @Override
    public HashMap searchTodayCheckin(int userId) {
        HashMap map = checkinDao.searchTodayCheckin(userId);
        return map;
    }

    @Override
    public long searchCheckinDays(int userId) {
        long days = checkinDao.searchCheckinDays(userId);
        return days;
    }

    @Override
    public ArrayList<HashMap> searchWeekCheckin(TimeRangeBaseDto timeRangeBaseDto) {
        List<String> normalDate = checkinDao.searchNormalCheckin((UserIdDto) timeRangeBaseDto);
        ArrayList holidaysList = holidaysDao.searchHolidaysInRange(timeRangeBaseDto);
        ArrayList workdayList = workdayDao.searchWorkdayInRange(timeRangeBaseDto);
        DateTime startDate = DateUtil.parseDate(timeRangeBaseDto.getStartDate());
        DateTime endDate = DateUtil.parseDate(timeRangeBaseDto.getEndDate());
        DateRange range = DateUtil.range(startDate, endDate, DateField.DAY_OF_MONTH);
        ArrayList<HashMap> list = new ArrayList<>();
        for (DateTime thisDate : range) {
            if (thisDate.isAfter(DateUtil.date())) {
                break;
            }
            String date = thisDate.toDateStr();
            String type = "工作日";
            if (thisDate.isWeekend()) {
                type = "节假日";
            }
            if (holidaysList != null && holidaysList.contains(date)) {
                type = "节假日";
            } else if (workdayList != null && workdayList.contains(date)) {
                type = "工作日";
            }
            String status = "";
            if (type.equals("工作日") && !normalDate.contains(thisDate.toDateStr())) {
                status = "异常";
            }
            HashMap map = new HashMap();
            map.put("date", date);
            map.put("status", status);
            map.put("type", type);
            map.put("day", thisDate.dayOfWeekEnum().toChinese("周"));
            list.add(map);

        }
        return list;
    }

    @Override
    public ArrayList<HashMap> searchMonthCheckin(TimeRangeBaseDto timeRangeBaseDto) {
        return this.searchWeekCheckin(timeRangeBaseDto);
    }

    @Override
    public CheckinVo searchDailyCheckin(Map<Object, Object> param) {
        CheckDateDto checkDateDto = new CheckDateDto();
        checkDateDto.setUserId((Integer) param.get("userId"));
        checkDateDto.setDate((String) param.get("date"));
        CheckinVo checkinVo = checkinDao.searchDailyCheckin(checkDateDto);
        if (checkinVo == null) {
            checkinVo = new CheckinVo();
            checkinVo.setCheckIn("未打卡");
            checkinVo.setCheckOut("未打卡");
        }
        ArrayList<String> imagePaths = tbImagePathDao.searchImagePaths((Integer) param.get("userId"),
                (String) param.get("date"));
        checkinVo.setImagePaths(imagePaths);
        return checkinVo;
    }
}


